// -------------------------------------------------------------------------------------
// RemoteCommand
// -------------------------------------------------------------------------------------
// Permission is granted to freely redistribute this source code, and to use fragments
// of this code in your own applications if you find them to be useful.  This class,
// along with the source code, come with no warranty of any kind, and the user assumes
// all responsibility for its use.
// -------------------------------------------------------------------------------------

#import <appkit/appkit.h>
#import <libc.h>
#import <stdlib.h>
#import <string.h>
#import <c.h>
#import <pwd.h>
#import <sys/param.h>
#import <sys/types.h>
#import <sys/time.h>
#import <sys/dir.h>
#import <remote/NXConnection.h>
#import "RemoteCommand.h"
#import "ExecServer.h"
#import "userInfo.h"
#import "AskOperator.h"
#import "ExecMonitor.h"

// -------------------------------------------------------------------------------------
// return path to application ("/appName" is removed from path)
// Note: This should be called at the beginning of the app to cache the app path name
const char *XAppPath()
{
	static char	*appPathName = (char*)nil;
	if (!appPathName) {
		char *p, path[MAXPATHLEN + 1];
    	if (NXArgv[0][0] == '/') strcpy(path, NXArgv[0]);
		else { 
			getwd(path);
			strcat(path, "/");
			strcat(path, NXArgv[0]);
		}
		if ((p = rindex(path, '/')) && (p != path)) *p = 0;
		appPathName = strcpy((char*)malloc(strlen(path) + 1), path);
	}
	return appPathName;
}

// -------------------------------------------------------------------------------------
@interface _RmtMethods : Object
- (const char*)getResponseForMessage:(askOperator_t*)ao;
@end

// -------------------------------------------------------------------------------------
@implementation RemoteCommand

// -------------------------------------------------------------------------------------
// create new ExecMonitor
// -------------------------------------------------------------------------------------

/* "Continue" select from NewExecMonitor panel (or "Cancel" if tag != 0) */
- newExecOk:sender
{
	[newExecWindow orderOut:self];
	if (![sender tag]) {
		const char *host = [newExecHost stringValue], *server = [newExecServer stringValue];
		if (![ExecMonitor newExecHost:host server:server]) {
			char *errMsg = "Unable to connect to server name \"%s\" on host \"%s\".  "
			               "'RemoteRunServer' may not have run successfully.";
			NXRunAlertPanel("Error", errMsg, "Continue",0,0, server, host);
		}
	}
	return self;
}

/* new monitor */
- newExecMonitor:sender
{
	char	localHost[MAXHOSTNAMELEN + 1], serverName[256];
	gethostname(localHost, sizeof(localHost));
	sprintf(serverName, "ExecServer_%s_%d", localHost, getpid());
	[newExecServer setStringValue:serverName];
	[newExecHost setStringValue:""];
	[newExecWindow center];
	[newExecWindow makeKeyAndOrderFront:(id)nil];
	return self;
}

// -------------------------------------------------------------------------------------
// menu actions
// -------------------------------------------------------------------------------------

/* application termination */
- terminate:sender
{
	return [super terminate:sender];
}

// -------------------------------------------------------------------------------------
// app name info
// -------------------------------------------------------------------------------------

- (const char*)appUserName
{
	return appUserName;
}

- (const char*)appUserHome
{
	return appUserHome;
}

- (const char*)appServerHost
{
	return appServerHost;
}

- (const char*)appServerName
{
	return appServerName;
}

// -------------------------------------------------------------------------------------
// application initialization
// -------------------------------------------------------------------------------------

/* application initialization */
- appDidInit:sender
{
	id			rmtMethods;
	char		userName[256], userHome[MAXPATHLEN + 1];
	char		host[MAXHOSTNAMELEN + 1], server[256];
	
	/* run-time initialization */
	XAppPath();

	/* get user name */
	if (!XMyUserName(userName) || !XUserHomeDirectory(userName, userHome)) {
		NXLogError("[RemoteCommand] Unable to get current user name/home");
		[self terminate:(id)nil];
		exit(2);
	}
	appUserName = NXCopyStringBuffer(userName);
	appUserHome = NXCopyStringBuffer(userHome);

	/* remote methods object for _askop (never freed) */
	rmtMethods = [[_RmtMethods alloc] init];
	
	/* get serverName and register for _askop server */
	gethostname(host, sizeof(host));
	appServerHost = NXCopyStringBuffer(host);
	sprintf(server, "%s_%s_%d", ASK_SERVER, appServerHost, getpid());
	appServerName = NXCopyStringBuffer(server);
	[[NXConnection registerRoot:rmtMethods withName:appServerName] runFromAppKit];

	/* new exec monitor */
	[self newExecMonitor:self];
	
	return self;
}

@end

// -------------------------------------------------------------------------------------
// Remote methods (called by '_askop')
// -------------------------------------------------------------------------------------
@implementation _RmtMethods

/* show panel and get user response */
- (const char*)getResponseForMessage:(askOperator_t*)ao
{
	return [AskOperator showAskPanel:ao];
	// free ao ?
}

@end
